﻿using System;
using System.Collections.Generic;
using NHibernate.Criterion;
using WuDada.Core.Persistence;
using WuDada.Core.Persistence.Ado;
using WuDada.Trade.DataLoader.Domain;

namespace WuDada.Trade.DataLoader.Persistence
{
    public class DataLoadDao : AdoDao, IDataLoadDao
    {
        public INHibernateDao NHibernateDao { get; set; }

        /// <summary>
        /// 新增股票歷史資料
        /// </summary>
        /// <param name="stockDataVO">被新增的股票歷史資料</param>
        /// <returns>新增後的股票歷史資料</returns>
        public StockDataVO CreateStockData(StockDataVO stockDataVO)
        {
            NHibernateDao.Insert(stockDataVO);

            return stockDataVO;
        }

        /// <summary>
        /// 更新股票歷史資料
        /// </summary>
        /// <param name="stockDataVO">被更新的股票歷史資料</param>
        /// <returns>更新後的股票歷史資料</returns>
        public StockDataVO UpdateStockData(StockDataVO stockDataVO)
        {
            NHibernateDao.Update(stockDataVO);

            return stockDataVO;
        }

        /// <summary>
        /// 刪除股票歷史資料
        /// </summary>
        /// <param name="stockDataVO">被刪除的股票歷史資料</param>
        public void DeleteStockData(StockDataVO stockDataVO)
        {
            NHibernateDao.Delete(stockDataVO);
        }

        /// <summary>
        /// 取得股票歷史資料 By 識別碼
        /// </summary>
        /// <param name="stockDataId">識別碼</param>
        /// <returns>股票歷史資料</returns>
        public StockDataVO GetStockDataById(int stockDataId)
        {
            return NHibernateDao.GetVOById<StockDataVO>(stockDataId);
        }

        /// <summary>
        /// 取得股票歷史資料 By 股票代碼 And 資料日期/時間
        /// </summary>
        /// <param name="stockCode">股票代碼</param>
        /// <param name="dataTime">資料日期/時間</param>
        /// <returns>股票歷史資料</returns>
        public StockDataVO GetStockData(string stockCode, DateTime dataTime)
        {
            DetachedCriteria dCriteria = DetachedCriteria.For<StockDataVO>();
            dCriteria.Add(Expression.Eq("StockCode", stockCode));
            dCriteria.Add(Expression.Eq("DataTime", dataTime));

            int count = NHibernateDao.CountByDetachedCriteria(dCriteria);

            if (count == 0)
            {
                return null;
            }

            return NHibernateDao.SearchByDetachedCriteria<StockDataVO>(dCriteria, 0, 1)[0];
        }

        /// <summary>
        /// 取得股票歷史資料清單
        /// </summary>
        /// <param name="queryString">搜尋語法，用Where...order by ...</param>
        /// <param name="pageIndex">分頁索引</param>
        /// <param name="pageSize">分頁大小</param>
        /// <returns>股票歷史資料清單</returns>
        public IList<StockDataVO> GetStockDataList(string queryString, int pageIndex, int pageSize)
        {
            return NHibernateDao.SearchByWhere<StockDataVO>(queryString, pageIndex, pageSize);
        }

        /// <summary>
        /// 取得股票歷史資料清單
        /// </summary>
        /// <param name="queryString">搜尋語法，用Where...order by ...</param>
        /// <returns>股票歷史資料清單</returns>
        public IList<StockDataVO> GetStockDataList(string queryString)
        {
            return NHibernateDao.SearchByWhere<StockDataVO>(queryString);
        }

        /// <summary>
        /// 取得股票歷史資料清單
        /// </summary>
        /// <param name="stockCode">股票代碼</param>
        /// <param name="period">資料週期類型</param>
        /// <param name="startDate">起始時間</param>
        /// <param name="endDate">結束時間</param>
        /// <param name="pageIndex">分頁索引</param>
        /// <param name="pageSize">分頁大小</param>
        /// <param name="sortField">排序欄位</param>
        /// <param name="sortDesc">升降冪排序</param>
        /// <returns>股票歷史資料清單</returns>
        public IList<StockDataVO> GetStockDataList(string stockCode, StockDataVO.StockDataPeriod period, DateTime? startDate, DateTime? endDate, int pageIndex, int pageSize, string sortField, bool sortDesc)
        {
            DetachedCriteria dCriteria = DetachedCriteria.For<StockDataVO>();

            if (!string.IsNullOrEmpty(stockCode))
            {
                dCriteria.Add(Expression.Eq("StockCode", stockCode));
            }

            dCriteria.Add(Expression.Eq("Period", (int)period));

            if (startDate != null)
            {
                dCriteria.Add(Expression.Ge("DataTime", startDate));
            }
            if (endDate != null)
            {
                dCriteria.Add(Expression.Le("DataTime", endDate));
            }

            if (!string.IsNullOrEmpty(sortField))
            {
                if (sortDesc)
                {
                    dCriteria.AddOrder(Order.Desc(sortField));
                }
                else
                {
                    dCriteria.AddOrder(Order.Asc(sortField));
                }
            }

            int count = NHibernateDao.CountByDetachedCriteria(dCriteria);

            if (count == 0)
            {
                return null;
            }

            return NHibernateDao.SearchByDetachedCriteria<StockDataVO>(dCriteria, pageIndex, pageSize);
        }

        /// <summary>
        /// 取得股票歷史資料清單
        /// </summary>
        /// <param name="stockCode">股票代碼</param>
        /// <param name="period">資料週期類型</param>
        /// <param name="startDate">起始時間</param>
        /// <param name="endDate">結束時間</param>
        /// <param name="sortField">排序欄位</param>
        /// <param name="sortDesc">升降冪排序</param>
        /// <returns>股票歷史資料清單</returns>
        public IList<StockDataVO> GetStockDataList(string stockCode, StockDataVO.StockDataPeriod period, DateTime? startDate, DateTime? endDate, string sortField, bool sortDesc)
        {
            DetachedCriteria dCriteria = DetachedCriteria.For<StockDataVO>();

            if (!string.IsNullOrEmpty(stockCode))
            {
                dCriteria.Add(Expression.Eq("StockCode", stockCode));
            }

            dCriteria.Add(Expression.Eq("Period", (int)period));

            if (startDate != null)
            {
                dCriteria.Add(Expression.Ge("DataTime", startDate));
            }
            if (endDate != null)
            {
                dCriteria.Add(Expression.Le("DataTime", endDate));
            }

            if (!string.IsNullOrEmpty(sortField))
            {
                if (sortDesc)
                {
                    dCriteria.AddOrder(Order.Desc(sortField));
                }
                else
                {
                    dCriteria.AddOrder(Order.Asc(sortField));
                }
            }

            int count = NHibernateDao.CountByDetachedCriteria(dCriteria);

            if (count == 0)
            {
                return null;
            }

            return NHibernateDao.SearchByDetachedCriteria<StockDataVO>(dCriteria);
        }

        /// <summary>
        /// 取得股票歷史資料筆數
        /// </summary>
        /// <param name="stockCode">股票代碼</param>
        /// <param name="period">資料週期類型</param>
        /// <param name="startDate">起始時間</param>
        /// <param name="endDate">結束時間</param>
        /// <returns>股票歷史資料筆數</returns>
        public int CountStockData(string stockCode, StockDataVO.StockDataPeriod period, DateTime? startDate, DateTime? endDate)
        {
            DetachedCriteria dCriteria = DetachedCriteria.For<StockDataVO>();

            if (!string.IsNullOrEmpty(stockCode))
            {
                dCriteria.Add(Expression.Eq("StockCode", stockCode));
            }

            dCriteria.Add(Expression.Eq("Period", (int)period));

            if (startDate != null)
            {
                dCriteria.Add(Expression.Ge("DataTime", startDate));
            }
            if (endDate != null)
            {
                dCriteria.Add(Expression.Le("DataTime", endDate));
            }

            return NHibernateDao.CountByDetachedCriteria(dCriteria);
        }
    }
}
